package com.sora.sora.security.login.filter;

import com.sora.sora.security.login.JwtManager;
import com.sora.sora.security.login.mapper.LoginMapper;
import com.sora.sora.security.login.service.impl.LoginServiceImpl;
import io.jsonwebtoken.Claims;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class LoginFilter extends OncePerRequestFilter {

    @Resource
    LoginMapper loginMapper;

    @Resource
    JwtManager jwtManager;

    @Resource
    LoginServiceImpl loginService;


    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        Claims accessToken = jwtManager.parserAccessToken(httpServletRequest.getHeader("access-token"));

        String username;
        String email;
        if (accessToken != null) {
            username = accessToken.getSubject();
            authen(username);
        } else {
            Claims refreshToken = jwtManager.parseRefreshToken(httpServletRequest.getHeader("refresh-token"));
            if (refreshToken != null) {
                email = refreshToken.getSubject();
                authen(email);
                // 此时accessToken已经过期，派发新的accesstoken
                username = loginMapper.queryNameByEmail(email);
                httpServletResponse.setHeader("access-token", jwtManager.generateAccessToken(username));
                // 判断refreshToken寿命，若过期时间小于等于 (refreshToken生命时间-accessToken过期时间)/2，则派发新的refreshToken
                long life = System.currentTimeMillis() - refreshToken.getIssuedAt().getTime();
                if (life > jwtManager.getInterval() / 2) {
                    System.out.println(life);
                    httpServletResponse.setHeader("refresh-token", jwtManager.generateRefreshToken(email));
                }
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    protected void authen(String username) {
        UserDetails userDetails = loginService.loadUserByUsername(username);
        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }


}
